#include <iostream>
#include <pthread.h>
#include <vector>
#include <string>
#include <cassert>
#include <unistd.h>

using namespace std;

static int num = 0;


class ThreadData 
{
public:
    pthread_t tid;
    char namebuffer[64];
};

class ThreadResult
{
public:
    int return_code;
    int return_result;
};

const char* fun()
{
    return "fun() is running! ";
}

// void test_add()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid, nullptr, pthread_routine, (void*)"thread one");
//     assert(n == 0);
//     (void)n;

//     // while(1)
//     // {
//     //     cout << "我是一个main pthread! num is " << ++num << endl;
//     //     cout << fun() << endl;
//     //     sleep(1);
//     // }  
//     for(int i = 0; i <= 10000; ++i)
//     {
//         ++num;
//     }
//     sleep(3);
//     cout << "num 的值为: " << num << endl;
// }

void* pthread_routine(void* args)
{
    //string name = static_cast<char*>(args);
    ThreadData* td = static_cast<ThreadData*>(args);

    int cnt = 10;
    while(cnt--)
    {
        // cout << "i am a new pthread! my name is " << td->namebuffer << endl;
        // cout << fun() << endl;
        cout << cnt  << " : &cnt " << &cnt << endl;
        sleep(1);
    }
    // ThreadResult* rt = new ThreadResult;
    // rt->return_code = 1;
    // rt->return_result = 420;
    return (void*)100;
}

int main()
{
    //test_add();
#define NUM 10

    vector<ThreadData*> threads;
    for(int i = 0; i < NUM; ++i)
    {
        ThreadData* td = new ThreadData;
        snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);
        pthread_create(&td->tid, nullptr, pthread_routine, td);
        threads.push_back(td);
    }
    sleep(5);
    for(int i = 0; i < NUM/2; ++i)
    {
        pthread_cancel(threads[i]->tid);
        cout << "cancel thread :" << threads[i]->namebuffer << "success!" << endl;
    }

    for(int i = 0; i < NUM; ++i)
    {
        // ThreadResult* result = nullptr;
        void* result = nullptr;
        pthread_join(threads[i]->tid, (void**)&result);
        (ThreadResult**)result;
        // cout << "code is :" << result->return_code << endl;
        // cout << "result is :" << result->return_result << endl;
         cout << "result is :" << (long long)result << endl;
        delete threads[i];
    }

    return 0;
}